#pragma once

#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
const std::string gpipeFile = "./fifo";
const mode_t pri = 0600;

const int defualtFd = -1;
const int gfifosize = 1024;
const int gForRead = O_RDONLY;
const int gForWrite = O_WRONLY;

class Fifo
{
private:
    int _fd;
    void openFifo(int flag)
    {
        int _fd = ::open(gpipeFile.c_str(), flag);
        if (_fd < 0)
        {
            std::cerr << "open error" << std::endl;
        }
    }

public:
    Fifo();
    ~Fifo();
    int wait()
    {
        int code = 0;
        ssize_t n = ::read(_fd, &code, sizeof code);

        if (n == sizeof code)
        {
            return 0;
        }
        else if (n == 0)
            return 1;
        else
            return 2;
    }
    void signal()
    {
        int code;
        ::write(_fd, &code, sizeof code);
    }
    bool openPipeForWrite()
    {
        openFifo(gForWrite);
        if (_fd < 0)
        {
            return false;
        }
        return true;
    }
    bool openPipeForRead()
    {
        openFifo(gForRead);
        if (_fd < 0)
        {
            return false;
        }
        return true;
    }
};

Fifo::Fifo() : _fd(-1)
{
    umask(0);
    int n = ::mkfifo(gpipeFile.c_str(), pri);
    if (n < 0)
    {
        // std::cerr << "mkfifo error" << std::endl;
        return;
    }
    std::cout << "mkfifo success" << std::endl;
    // sleep(5);
}

Fifo::~Fifo()
{
    if (_fd >= 0)
        ::close(_fd);
    int n = ::unlink(gpipeFile.c_str());
    if (n < 0)
    {
        std::cerr << "unlink error" << std::endl;
        return;
    }
    std::cout << "unlink success" << std::endl;
}

Fifo piPe;
